<?php
/**
 * Permission Service
 * User: zng
 * Date: 2019/11/4
 * Time: 14:34
 */
namespace app\admin\service;

use app\admin\model\admin\Permission as PermissionModel;
use app\exceptions\OrdinaryException;
use app\admin\traits\service\Application;
use think\{
    Exception,Request
};

Class Permission {

    use Application;

    /**
     * 首页列表
     * @param array $get 筛选条件
     * @author zx
     * @date 2019-11-12
     * @return \think\Paginator
     */
    public function indexPaginate( array $get=[] )
    {
        $map = [];
        if ( get($get, 'name') ) {
            $map[] = ['name', 'LIKE', $get['name'].'%'];
        }
        if ( get($get, 'status') === 0 || get($get, 'status') === '0' || get($get, 'status') == 1 ) {
            $map[] = ['status', '=', $get['status']];
        }
        if ( get($get, 'start_create_at') ) {
            $map[] = ['create_time', '>=', strtotime($get['start_create_at'].' 00:00:00')];
        }
        if ( get($get, 'end_create_at') ) {
            $map[] = ['create_time', '<=', strtotime($get['end_create_at'].' 23:59:59')];
        }
        if ( get($get, 'category_id') ) {
            $map[] = ['category_id', '=', $get['category_id']];
        }
        $pageSize = get($get,'pageSize')>0?$get['pageSize']:20;
        return PermissionModel::with('permissionCategory')->where($map)
            ->order('id', 'desc')
            ->paginate($pageSize);
    }

    /**
     * 状态更改
     * @author zx
     * @date 2019-11-14
     * @return \think\response
     */
    public function status(PermissionModel $permissionModel)
    {
        $status = (int)(!$permissionModel->status);
        $permissionModel->status = $status;
        $update = $permissionModel->save();
        if ( $update ) {
            return success(['status'=>$status]);
        }
        return failed('更新失败');
    }

    /**
     * 新增\编辑分组信息
     * @param array $data 数据包
     * @author zx
     * @date 2019-11-14
     * @throws OrdinaryException
     * @return boolean
     */
    public function create(array $data)
    {
        try{
            app('rbac')->createPermission($data);
        } catch ( Exception $exception ) {
            throw new OrdinaryException($exception->getMessage());
        }
        return true;
    }

    /**
     * 获取分组信息
     * @param mixed $param 条件
     * @author zx
     * @date 2019-11-15
     * @throws OrdinaryException
     * @return mixed
     */
    public function get( $param )
    {
        try{
            $data = app('rbac')->getPermission( $param );
        } catch ( Exception $exception ) {
            throw new OrdinaryException($exception->getMessage());
        }
        return $data;
    }

    /**
     * 批量删除
     * @param mixed $data
     * @author zx
     * @date 2019-11-15
     * @throws OrdinaryException
     * @return boolean
     */
    public function destory( $data )
    {
        try{
            $bool = app('rbac')->delPermission( $data );
        } catch ( Exception $exception ) {
            throw new OrdinaryException($exception->getMessage());
        }
        return $bool;
    }

    /**
     * 生成权限分组树
     * @author zx
     * @date 2019-11-18
     * @throws OrdinaryException
     * @return array
     */
    public function tree():array
    {
        $category = app('permission_category_service')->get([['status', '=', 1]]);
        $tree = [];
        foreach ( $category as $key => $_category ) {
            $tree[$key] = [
                'id' => $_category['id'],
                'name' => $_category['name'],
                'children' => $this->get([
                    ['type','=',1],
                    ['category_id', '=', $_category['id']],
                    ['status', '=', 1]
                ])
            ];
        }
        return $tree;
    }

    /**
     * 自动更新权限及权限分组
     * @author zx
     * @date 2019-11-19
     * @throws OrdinaryException
     * @return mixed
     */
    public function auto()
    {
        //获取控制器分组文件名
        $groups = $this->group();
        //查询所有路由列表
        $permission_path = $this->getPath();
        $config = config('permission.');
        //更新权限分组表
        if ( ! $this->updatePermissionCategory( $config['category'] ) ) {
            throw new OrdinaryException('权限分组表更新失败');
        }
        $permission_category_path = app('permission_category_service')->getPath();
        $count = 0;
        foreach ( $groups as $_group ) {
            $controllers = $this->controller( $_group, $config['exclude_controller'] );
            if ( !$controllers ) continue;
            foreach ( $controllers as $_controller ) {
                if ( !$_controller ) continue;
                $permission_category_name = ($_group?$_group.'/':'').$_controller;
                if ( !in_array($permission_category_name, $permission_category_path) ) continue;
                $category = app('permission_category_service')->get([['path','=',$permission_category_name],['status','=',1]]);
                if ( ! $category ) {
                    throw new OrdinaryException('暂无分组信息');
                }
                $category_id = $category[0]['id'];
                $controller_name = 'admin/'.$permission_category_name;
                $actions = $this->action($controller_name);
                if ( !$actions ) continue;
                foreach ( $actions as $_action ) {
                    if ( !$_action ) continue;
                    $path = $controller_name.'/'.$_action;
                    if ( in_array( $path, $config['exclude'] ) || in_array( $path, $permission_path ) || in_array($_action, $config['currency_exclude_action']) ) continue;
                    $permission_name = $config['currency_name'][$_action]??$_action;
                    if ( isset( $config['title'][$path] ) ) {
                        $permission_name = $config['title'][$path];
                    }
                    if ($this->create([
                        'name' => $category[0]['name'].$permission_name,
                        'description' => '负责监控'.$permission_name,
                        'status' => 1,
                        'type' => 1,
                        'path' => $path,
                        'category_id' => $category_id,
                        'create_time' => time()
                    ])) {
                        $count++;
                    }
                }
            }
        }
        if ( $count <= 0 ) {
            return failed('暂无可更新权限');
        }

    }

    /**
     * 获取当前路径
     * @return array
     */
    public function path(Request $request)
    {
        $module = $request->module();
        $controller = explode('.', $request->controller());
        $action = $request->action(true);
        $group_controller_name = $controller[0];
        if ( count($controller) === 2 ) {
            $group_controller_name = lcfirst($controller[0]).'/'.$controller[1];
        }
        return [
            'path' => $module.'/'.$group_controller_name.'/'.$action,
            'module' => $module,
            'group_controller' => $group_controller_name,
            'action' => $action
        ];
    }

    /**
     * 获取所有路径
     * @return array
     */
    public function getPath():array
    {
        return PermissionModel::status()->order('name', 'asc')->column('path');
    }

}